#ifndef CROUTECONDITIONS_H
#define CROUTECONDITIONS_H

#include "common.h"
#include "singleton.h"
#include "cjson.h"
#include "wbasenode.h"
#include "wsignallampnode.h"
#include "wswitchnode.h"

#include <mutex>

struct tagSwitchCondiItem : public NedAllocatedObject
{
    tagSwitchCondiItem():switchnode(NULL),switchstate(SwitchState::NOINIT) {}
    tagSwitchCondiItem(WSwitchNode *node,SwitchState sstate)
        : switchnode(node),switchstate(sstate) {}

    WSwitchNode *switchnode;
    int switchstate;
};

struct tagRouteCondiItem : public NedAllocatedObject
{
    inline void removeconflictsignals(wxString signalName)
    {
        wxVector<WSignalLampNode*>::iterator iter = conflictsignals.begin();
        for(;iter != conflictsignals.end();++iter)
        {
            if((*iter)->getName() == signalName)
            {
                conflictsignals.erase(iter);
                break;
            }
        }
    }

    inline void removeconflictswitch(wxString switchName)
    {
        wxVector<tagSwitchCondiItem>::iterator iter = conflictswitch.begin();
        for(;iter != conflictswitch.end();++iter)
        {
            if((*iter).switchnode->getName() == switchName)
            {
                conflictswitch.erase(iter);
                break;
            }
        }
    }

    inline void removefollowswitch(wxString switchName)
    {
        wxVector<tagSwitchCondiItem>::iterator iter = followswitch.begin();
        for(;iter != followswitch.end();++iter)
        {
            if((*iter).switchnode->getName() == switchName)
            {
                followswitch.erase(iter);
                break;
            }
        }
    }

    WSignalLampNode* getconflictsignals(wxString signalName)
    {
        wxVector<WSignalLampNode*>::iterator iter = conflictsignals.begin();
        for(;iter != conflictsignals.end();++iter)
        {
            if((*iter)->getName() == signalName)
                return (*iter);
        }

        return NULL;
    }

    tagSwitchCondiItem* getconflictswitch(wxString switchName)
    {
        wxVector<tagSwitchCondiItem>::iterator iter = conflictswitch.begin();
        for(;iter != conflictswitch.end();++iter)
        {
            if((*iter).switchnode->getName() == switchName)
                return &(*iter);
        }

        return NULL;
    }

    tagSwitchCondiItem* getfollowswitch(wxString switchName)
    {
        wxVector<tagSwitchCondiItem>::iterator iter = followswitch.begin();
        for(;iter != followswitch.end();++iter)
        {
            if((*iter).switchnode->getName() == switchName)
                return &(*iter);
        }

        return NULL;
    }

    wxString startLight;                           // 开始灯
    wxString endLight;                             // 结束灯
    wxVector<WSignalLampNode*> conflictsignals;    // 敌对信号灯
    wxVector<tagSwitchCondiItem> conflictswitch;   // 敌对道岔
    wxVector<tagSwitchCondiItem> followswitch;     // 带动道岔
};

class CRouteConditions : public Singleton<CRouteConditions>
{
public:
    CRouteConditions();
    ~CRouteConditions();

    /// 解析Json
    void parsingJson(cJSON *routecondi);
    /// 添加一个进路条件到系统中
    bool addRouteCondiItem(tagRouteCondiItem pRouteCondiItem);
    /// 得到指定进路的敌对条件
    tagRouteCondiItem* getRouteCondiItem(wxString startNode,wxString endNode);
    /// 得到所有的进路关系
    inline std::map<wxString,std::map<wxString,tagRouteCondiItem>> getAllRouteConditions(void) { return m_RouteConditions; }
    /// 清除所有的数据
    inline void clearAllData(void) { m_RouteConditions.clear(); }

private:
    std::map<wxString,std::map<wxString,tagRouteCondiItem>> m_RouteConditions;
    mutable std::mutex m_RouteConditionsMutex;
};

#endif // CROUTECONDITIONS_H
